import pandas as pd
from datetime import datetime, timedelta
import random
from faker import Faker
import ipywidgets as widgets
from IPython.display import display, clear_output

# 初始化Faker生成测试数据，使用中文环境
fake = Faker('zh_CN')


def generate_ticket_data(num_tickets=100):
    """生成模拟工单数据

    Args:
        num_tickets (int): 要生成的工单数量，默认为100

    Returns:
        pd.DataFrame: 包含生成工单数据的DataFrame
    """
    # 定义工单可能的属性值
    tickets = []
    statuses = ['待处理', '处理中', '已解决', '已关闭', '重新打开']
    priorities = ['低', '中', '高', '紧急']
    categories = ['搜索结果异常', '排序问题', '商品未展示', '搜索建议错误', '其他']

    for _ in range(num_tickets):
        # 生成随机时间范围在最近30天内的创建时间和更新时间
        create_time = fake.date_time_between(start_date='-30d', end_date='now')
        update_time = create_time + timedelta(days=random.randint(0, 7))

        # 构造单个工单数据字典
        ticket = {
            '工单ID': f'T{random.randint(10000, 99999)}',
            '提交时间': create_time,
            '最后更新时间': update_time,
            '提交用户': fake.name(),  # 使用Faker生成中文姓名
            '用户ID': f'UID{random.randint(100000, 999999)}',
            '问题类型': random.choice(categories),
            '优先级': random.choice(priorities),
            '状态': random.choice(statuses),
            '关键词': fake.word() + " " + fake.word(),  # 生成两随机关键词
            '问题描述': fake.sentence(nb_words=10),  # 生成10个单的句子
            '关联商品ID': f'SPU{random.randint(10000, 99999)}',
            '处理人员': random.choice(['张三', '李四', '王五', '赵六', '钱七', '未分配']),
            '解决备注': fake.sentence(nb_words=8) if random.random() > 0.3 else ""  # 70%概率生成备注
        }
        tickets.append(ticket)

    return pd.DataFrame(tickets)


class AlibabaSearchTicketSystem:
    """阿里电商搜索工单管理系统核心类"""

    def __init__(self):
        """初始化系统，生成50条模拟工单数据"""
        self.df = generate_ticket_data(50)
        self.filtered_df = self.df.copy()

    def search_tickets(self, keyword=None, status=None, assignee=None, start_date=None, end_date=None):
        """根据多种条件搜索工单

        Args:
            keyword (str): 搜索关键词，匹配问题描述、关键词或工单ID
            status (str): 工单状态筛选条件
            assignee (str): 处理人员筛选条件
            start_date (datetime): 提交时间起始范围
            end_date (datetime): 提交时间结束范围

        Returns:
            pd.DataFrame: 符合筛选条件的工单DataFrame
        """
        df = self.df.copy()

        # 关键词搜索（不区分大小写）
        if keyword:
            keyword = keyword.lower()
            mask = (df['问题描述'].str.lower().str.contains(keyword) |
                    df['关键词'].str.lower().str.contains(keyword) |
                    df['工单ID'].str.lower().str.contains(keyword))
            df = df[mask]

        # 状态筛选
        if status and status != '全部':
            df = df[df['状态'] == status]

        # 处理人筛选
        if assignee and assignee != '全部':
            df = df[df['处理人员'] == assignee]

        # 时间范围筛选
        if start_date and end_date:
            df = df[(df['提交时间'] >= start_date) & (df['提交时间'] <= end_date)]
        elif start_date:
            df = df[df['提交时间'] >= start_date]
        elif end_date:
            df = df[df['提交时间'] <= end_date]

        self.filtered_df = df
        return df

    def get_ticket_details(self, ticket_id):
        """获取指定工单的详细信息

        Args:
            ticket_id (str): 要查询的工单ID

        Returns:
            dict: 工单详细信息字典，如果不存在返回None
        """
        ticket = self.df[self.df['工单ID'] == ticket_id]
        if ticket.empty:
            return None
        return ticket.iloc[0].to_dict()

    def update_ticket_status(self, ticket_id, new_status):
        """更新工单状态

        Args:
            ticket_id (str): 要更新的工单ID
            new_status (str): 新的状态值

        Returns:
            bool: 更新是否成功
        """
        if ticket_id not in self.df['工单ID'].values:
            return False

        self.df.loc[self.df['工单ID'] == ticket_id, '状态'] = new_status
        self.df.loc[self.df['工单ID'] == ticket_id, '最后更新时间'] = datetime.now()
        return True

    def add_note_to_ticket(self, ticket_id, note):
        """为工单添加解决备注

        Args:
            ticket_id (str): 要添加备注的工单ID
            note (str): 备注内容

        Returns:
            bool: 添加是否成功
        """
        if ticket_id not in self.df['工单ID'].values:
            return False

        # 如果已有备注，则追加新备注并添加时间戳
        current_note = self.df.loc[self.df['工单ID'] == ticket_id, '解决备注'].values[0]
        new_note = f"{current_note} | {datetime.now().strftime('%Y-%m-%d')}: {note}" if current_note else note
        self.df.loc[self.df['工单ID'] == ticket_id, '解决备注'] = new_note
        return True


class TicketSystemUI:
    """工单系统交互式界面类"""

    def __init__(self):
        """初始化UI组件"""
        self.system = AlibabaSearchTicketSystem()
        self.output = widgets.Output()  # 用于显示输出的区域

        # 创建搜索控件
        self.keyword_input = widgets.Text(placeholder='输入关键词/工单ID...', description='搜索:')
        self.status_dropdown = widgets.Dropdown(
            options=['全部', '待处理', '处理中', '已解决', '已关闭', '重新打开'],
            value='全部',
            description='状态:'
        )
        self.assignee_dropdown = widgets.Dropdown(
            options=['全部', '张三', '李四', '王五', '赵六', '钱七', '未分配'],
            value='全部',
            description='处理人:'
        )
        # 日期选择控件
        self.start_date_picker = widgets.DatePicker(description='开始日期:')
        self.end_date_picker = widgets.DatePicker(description='结束日期:')
        self.search_button = widgets.Button(description="搜索工单")
        self.search_button.on_click(self.display_tickets)

        # 创建管理控件
        self.ticket_id_input = widgets.Text(placeholder='输入工单ID', description='工单ID:')
        self.status_update = widgets.Dropdown(
            options=['待处理', '处理中', '已解决', '已关闭', '重新打开'],
            description='新状态:'
        )
        self.note_input = widgets.Text(placeholder='输入备注...', description='备注:')
        self.update_button = widgets.Button(description="更新状态")
        self.note_button = widgets.Button(description="添加备注")
        self.update_button.on_click(self.update_status)
        self.note_button.on_click(self.add_note)

        # 布局设置
        search_box = widgets.VBox([
            widgets.HBox([self.keyword_input, self.status_dropdown, self.assignee_dropdown]),
            widgets.HBox([self.start_date_picker, self.end_date_picker]),
            self.search_button
        ])

        manage_box = widgets.HBox([
            self.ticket_id_input,
            self.status_update,
            self.update_button,
            self.note_input,
            self.note_button
        ])

        self.dashboard = widgets.VBox([
            widgets.HTML("<h2>阿里电商搜索工单系统</h2>"),
            search_box,
            manage_box,
            self.output
        ])

    def display_ui(self):
        """显示整个UI界面"""
        display(self.dashboard)
        self.display_tickets()

    def display_tickets(self, btn=None):
        """显示工单搜索结果"""
        with self.output:
            clear_output()

            # 执行搜索
            start_date = self.start_date_picker.value
            end_date = self.end_date_picker.value

            results = self.system.search_tickets(
                keyword=self.keyword_input.value,
                status=self.status_dropdown.value,
                assignee=self.assignee_dropdown.value,
                start_date=start_date,
                end_date=end_date
            )

            # 显示统计信息
            status_counts = results['状态'].value_counts()
            print(f"找到工单: {len(results)} 个 | 待处理: {status_counts.get('待处理', 0)} | "
                  f"处理中: {status_counts.get('处理中', 0)} | 紧急工单: {len(results[results['优先级'] == '紧急'])}")

            # 显示前10条结果（按提交时间降序）
            display(results.sort_values('提交时间', ascending=False).head(10)[
                        ['工单ID', '提交时间', '状态', '优先级', '问题类型', '处理人员', '关键词']
                    ])

    def update_status(self, btn):
        """更新工单状态按钮回调函数"""
        ticket_id = self.ticket_id_input.value
        new_status = self.status_update.value

        if self.system.update_ticket_status(ticket_id, new_status):
            with self.output:
                clear_output()
                print(f"工单 {ticket_id} 状态已更新为: {new_status}")
            self.display_tickets()
        else:
            with self.output:
                clear_output()
                print(f"错误: 工单ID {ticket_id} 不存在!")

    def add_note(self, btn):
        """添加备注按钮回调函数"""
        ticket_id = self.ticket_id_input.value
        note = self.note_input.value

        if self.system.add_note_to_ticket(ticket_id, note):
            with self.output:
                clear_output()
                print(f"已为工单 {ticket_id} 添加备注")
            self.display_tickets()
        else:
            with self.output:
                clear_output()
                print(f"错误: 工单ID {ticket_id} 不存在!")


if __name__ == "__main__":
    # 生成示例数据报表
    df = generate_ticket_data(20)
    print("示例工单数据:")
    display(df.head())

    # 启动交互式系统
    print("\n\n启动交互式工单系统...")
    ui = TicketSystemUI()
    ui.display_ui()
